﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using JinianNet.JNTemplate;

namespace JinianNet.JNCms
{
    public class Global
    {
        public static void RegisteAllConfigs()
        {
            AreaRegistration.RegisterAllAreas();
            RegisterViewEngines(ViewEngines.Engines);
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
            //RegisterTemplateFuncs(JNTemplate.BuildManager.);
            RegisterResources();
            RegisterTemplateConfigs(BuildManager.Engines);

        }

        private static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Manage",
                "Manage/{action}",
                new { controller = "Manage", theme = JinianNet.JNCms.Config.Site.Theme }, // Parameter defaults
                new string[]{
                    "JinianNet.JNCms.Controllers"
                });

            routes.MapRoute(
                "Api",
                "Api/{controller}/{action}",
                new { theme = JinianNet.JNCms.Config.Site.Theme }, // Parameter defaults
                new string[]{
                                "JinianNet.JNCms.Api"
                });

            routes.MapRoute(
                "System",
                "Manage/{controller}/{action}/{item}/{page}",
                new { theme = JinianNet.JNCms.Config.Site.Theme, item = UrlParameter.Optional, page = UrlParameter.Optional }, // Parameter defaults
                new { page = "^[\\d]*$" },
                new string[]{
                    "JinianNet.JNCms.Controllers"
                });

            routes.MapRoute(
                "Server",
                "Server/{action}/{item}",
                new { controller = "Server", theme = JinianNet.JNCms.Config.Site.Theme, item = UrlParameter.Optional }, // Parameter defaults
                new string[]{
                    "JinianNet.JNCms.Controllers"
                });

            routes.MapRoute(
                "Ajax",
                "Ajax/{action}/{item}",
                new { controller = "Ajax", theme = JinianNet.JNCms.Config.Site.Theme, item = UrlParameter.Optional }, // Parameter defaults
                new string[]{
                    "JinianNet.JNCms.Controllers"
                });

            routes.MapRoute(
                "home",
                "{action}/{item}/{page}",//   Page/About   Article/Title
                new { controller = "Home", action = "Index", theme = JinianNet.JNCms.Config.Site.Theme, item = UrlParameter.Optional, page = UrlParameter.Optional }, // Parameter defaults
                new { page = "^[\\d]*$" },
                new string[]{
                    "JinianNet.JNCms.Controllers"
                });
            
            //routes.MapRoute(
            //    "admin",
            //    "Manage/{action}",
            //    new { controller = "Manage", theme = JinianNet.JNCms.Config.Site.Theme },
            //    new string[]{
            //        "JinianNet.JNCms.Controllers"
            //    });

            //routes.MapRoute(
            //    "home",
            //    "{action}/{item}",//   Page/About   Article/Title
            //    new { controller = "Home", action = "Index", theme = JinianNet.JNCms.Config.Site.Theme, item = UrlParameter.Optional }, // Parameter defaults
            //    new string[]{
            //        "JinianNet.JNCms.Controllers"
            //    });

            //routes.MapRoute(
            //  "channel",
            //  "Channel/{item}/{page}",//   Page/About   Article/Title
            //  new { controller = "Home", action = "Channel", theme = JinianNet.JNCms.Config.Site.Theme, page = UrlParameter.Optional }, // Parameter defaults
            //  new string[]{
            //        "JinianNet.JNCms.Controllers"
            //    });


            //routes.MapRoute(
            //    "manage",
            //    "Manage/{controller}/{action}/{item}/{page}", // Manage/Article/List
            //    new { theme = JinianNet.JNCms.Config.Site.Theme, item = UrlParameter.Optional, page = UrlParameter.Optional },
            //    new { theme = JinianNet.JNCms.Config.Site.Theme },
            //    new string[]{
            //        "JinianNet.JNCms.Controllers"
            //    });

        }

        private static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        private static void RegisterViewEngines(ViewEngineCollection engines)
        {
            /*
             * 0 action
             * 1 controller
             * 2 area
             * 3 theam
             */
            engines.Clear();
            string[] tveConfig = new string[] { "~/Views/Template/{3}/{0}.html" };
            string[] rveConfig = new string[] { "~/Views/Manage/{1}/{0}.cshtml", "~/Views/{1}/{0}.cshtml" };
            RazorViewEngine rve = new RazorViewEngine();
            rve.AreaMasterLocationFormats = rveConfig;
            rve.AreaPartialViewLocationFormats = rveConfig;
            rve.AreaViewLocationFormats = rveConfig;
            rve.MasterLocationFormats = rveConfig;
            rve.PartialViewLocationFormats = rveConfig;
            rve.ViewLocationFormats = rveConfig;
            engines.Add(rve);
            engines.Add(new Web.MVC.TemplateViewEngine(tveConfig, tveConfig, tveConfig, tveConfig, tveConfig, tveConfig));
        }

        private static void RegisterResources()
        {
            Dictionary<string, string> dictionary = Config.Read("ScriptResource", false);
            if (dictionary != null)
            {
                foreach (KeyValuePair<string, string> value in dictionary)
                {
                    JinianNet.Web.ResourceManager.Script.Add(value.Key.TrimEnd(), value.Value.TrimEnd(';').Split(';'));
                }
            }

            dictionary = Config.Read("StyleResource", false);
            if (dictionary != null)
            {
                foreach (KeyValuePair<string, string> value in dictionary)
                {
                    JinianNet.Web.ResourceManager.Style.Add(value.Key.TrimEnd(), value.Value.TrimEnd(';').Split(';'));
                }
            }
        }

        //private static void RegisterTemplateFuncs(Dictionary<string, JinianNet.JNTemplate.FuncHandler> dictionary)
        //{
        //    dictionary.Add("Command", delegate(object[] args)
        //    {
        //        if (args == null || args.Length != 1)
        //            throw new Exception("agrs");
        //        return JNCms.Data.DataAccess.CreateDataProcess().ExecuteTable(args[0].ToString());
        //    });
        //    //Render
        //    dictionary.Add("Content", delegate(object[] args)
        //    {
        //        if (args == null || args.Length != 1)
        //            throw new Exception("agrs");
        //        var value = JNCms.Data.DataAccess.CreateContent().GetItem(args[0].ToString());
        //        if (value != null)
        //            return value.Text;
        //        return null;
        //    });

        //    dictionary.Add("ArticleItem", delegate(object[] args)
        //    {
        //        if (args == null || args.Length >= 1)
        //            throw new Exception("agrs");
        //        var model = JNCms.Data.DataAccess.CreateCategory().GetItem(args[0].ToString());
        //        if (args.Length == 1)
        //            return JNCms.Data.DataAccess.CreateArticle().GetList(model.ID, 1,Config.Page.Size);
        //        if (args.Length == 2)
        //            return JNCms.Data.DataAccess.CreateArticle().GetList(model.ID, 1, int.Parse(args[1].ToString()));
        //        if (args.Length == 3)
        //            return JNCms.Data.DataAccess.CreateArticle().GetList(model.ID, 1, int.Parse(args[1].ToString()));
        //        return null;
        //    });

        //    dictionary.Add("CategoryItem", delegate(object[] args)
        //    {
        //        if (args == null || args.Length != 1)
        //            throw new Exception("agrs");
        //        JinianNet.JNCms.Data.ICategory dal = JNCms.Data.DataAccess.CreateCategory();
        //        var model = dal.GetItem(args[0].ToString());
        //        return JNCms.Data.DataAccess.CreateCategory().GetList(int.Parse(args[0].ToString()));
        //    });

        //    dictionary.Add("LinksItem", delegate(object[] args)
        //    {
        //        if (args == null || args.Length != 1)
        //            throw new Exception("agrs");
        //        return JNCms.Data.DataAccess.CreateLinks().GetList(int.Parse(args[0].ToString()));
        //    });
        //}

        private static void RegisterTemplateConfigs(EngineCollection engines)
        {
            
            Engine en = new Engine(
                JinianNet.Common.Path.Concat(JinianNet.Web.HttpRunInfo.AppDomainAppPath,
                Config.Site.SiteDirectory,
                Config.Site.TemplateDirectory,
                Config.Site.Theme),
                System.Text.Encoding.UTF8);

            en.VariableScope["Command"]= new JinianNet.JNTemplate.FuncHandler(delegate(object[] args)
            {
                if (args == null || args.Length != 1)
                    throw new Exception("agrs");
                return JNCms.Data.DataAccess.CreateDataProcess().ExecuteTable(args[0].ToString());
            });
            //Render
            en.VariableScope["Content"]=  new JinianNet.JNTemplate.FuncHandler(delegate(object[] args)
            {
                if (args == null || args.Length != 1)
                    throw new Exception("agrs");
                var value = JNCms.Data.DataAccess.CreateContent().GetItem(args[0].ToString());
                if (value != null)
                    return value.Text;
                return null;
            });

            en.VariableScope["ArticleItem"]=  new JinianNet.JNTemplate.FuncHandler(delegate(object[] args)
            {
                if (args == null || args.Length == 0)
                    throw new Exception("agrs");
                int id;
                string value = args[0].ToString();
                if (!char.IsNumber(value[0]) || !int.TryParse(value, out id))
                {
                    var model = JNCms.Data.DataAccess.CreateCategory().GetItem(args[0].ToString());
                    if (model != null)
                    {
                        id = model.ID;
                    }
                    else
                    {
                        return null;
                    }
                }
               
                if (args.Length == 1)
                    return JNCms.Data.DataAccess.CreateArticle().GetList(id, 1, Config.Page.Size);
                if (args.Length == 2)
                    return JNCms.Data.DataAccess.CreateArticle().GetList(id, 1, int.Parse(args[1].ToString()));
                if (args.Length == 3)
                    return JNCms.Data.DataAccess.CreateArticle().GetList(id, 1, int.Parse(args[1].ToString()));
                return null;
            });

            en.VariableScope["CategoryItem"]=  new JinianNet.JNTemplate.FuncHandler(delegate(object[] args)
            {
                if (args == null || args.Length > 1)
                    throw new Exception("agrs");
                JinianNet.JNCms.Data.ICategory dal = JNCms.Data.DataAccess.CreateCategory();
                bool hasChild = (args.Length == 2 && (args[1].ToString() == "1" || args[1].ToString().Equals("true", StringComparison.OrdinalIgnoreCase)));
                return JNCms.Data.DataAccess.CreateCategory().GetList(int.Parse(args[0].ToString()), hasChild);
            });

            en.VariableScope["LinksItem"] = new JinianNet.JNTemplate.FuncHandler(delegate(object[] args)
            {
                if (args == null || args.Length != 1)
                    throw new Exception("agrs");
                return JNCms.Data.DataAccess.CreateLinks().GetList(int.Parse(args[0].ToString()));
            });

            en.VariableScope["CategoryView"] = new JinianNet.JNTemplate.FuncHandler(delegate(object[] args)
            {
                if (args == null || args.Length != 1)
                    throw new Exception("agrs");
                JinianNet.JNCms.Data.ICategory dal = JNCms.Data.DataAccess.CreateCategory();
                int id;
                string value = args[0].ToString();
                if (char.IsNumber(value[0]) && int.TryParse(value, out id))
                    return dal.GetItem(id);
                return dal.GetItem(value);
            });

            en.VariableScope["ArticleView"] = new JinianNet.JNTemplate.FuncHandler(delegate(object[] args)
            {
                if (args == null || args.Length != 1)
                    throw new Exception("agrs");
                return JNCms.Data.DataAccess.CreateArticle().GetItem(args[0].ToString());
            });

            engines.Clear();
            engines.Add(en);
        }

    }
}
